package com.yangfan.juc.locks;

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.IntStream;

/**
 * @description: 多生产者消费者 案例
 * @author: yangfan
 * @date: Created in 2020/3/27 0027 14:45
 * @modified By:
 */
public class ConditionExample {


    private static ReentrantLock lock = new ReentrantLock();

    private static Condition producerCondition = lock.newCondition();

    private static Condition consumerCondition = lock.newCondition();

    private static LinkedList<Long> DATA = new LinkedList<>();

    private static final int MAX_CONTAINMENT = 5;

    private static final int MIX_CONTAINMENT = 0;




    public static void main(String[] args) {

        IntStream.range(0, 2).forEach(x -> new Thread(() -> {
            while (true){
                consumer();
            }
        },"C-" + x ).start());


        IntStream.range(0, 3).forEach(x -> new Thread(() -> {
            while (true){
                producer();
            }
        },"P-" + x ).start());

    }




    public static void producer () {

        try{
            lock.lock();

            while (DATA.size() >= MAX_CONTAINMENT){
                try {
                    producerCondition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            sleep(1L);

            Long value = System.currentTimeMillis();
            DATA.addLast(value);//进行生产
            System.out.println(Thread.currentThread().getName() + "P"+ value );
            consumerCondition.signalAll();//通知消费者进行消费

        }finally {
            lock.unlock();
        }

    }



    public static void consumer () {

        try {

            lock.lock();

            while ( DATA.size() <= MIX_CONTAINMENT ){
                try {
                    consumerCondition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            sleep(1L);

            Long value = DATA.removeFirst();
            System.out.println(Thread.currentThread().getName() + "C"+ value );
            producerCondition.signalAll();//通知消费者进行消费

        }finally {
            lock.unlock();
        }


    }


    private static void sleep(Long sec){
        try {
            TimeUnit.SECONDS.sleep(sec);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }




}
